#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
using namespace std;

//int main()
//{
//	auto f1 = [](int x, int y) {return x + y; };
//	auto f2 = [](int x, int y) {return x + y; };
//	cout << typeid(f1).name() << endl;
//	cout << typeid(f2).name() << endl;
//
//	//f1 = f2;
//	
//
//	return 0;
//}


//int main()
//{
//	short a{ 65535 };
//
//	return 0;
//}

#include "SmartPtr.h"

//class A
//{
//public:
//	A(int a=0)
//		:_a(a)
//	{
//		cout << "A():a" << endl;
//	}
//
//	~A()
//	{
//		cout << "~A()" << endl;
//	}
//
//	int _a;
//};

//int main()
//{
//	gp::auto_ptr<A> p1(new A(1));
//	gp::auto_ptr<A> p2(new A(1));
//	gp::auto_ptr<A> p3(p1);
//
//
//	//cout << (*p1)._a << endl;
//
//	return 0;
//}

//int main()
//{
//	gp::unique_ptr<A> p1(new A(1));
//
//	cout << p1->_a << endl;
//
//	//gp::unique_ptr<A> p2(p1);
//
//
//	return 0;
//}


//int main()
//{
//	gp::shared_ptr<A> p1(new A(1));
//	gp::shared_ptr<A> p2(new A(2));
//	gp::shared_ptr<A> p3(p1);
//
//	p1 = p2;
//
//	return 0;
//}

struct Node
{
	Node(int val=0)
		:_val(val)
	{
		cout << "Node()" << endl;
	}

	~Node()
	{
		cout << "~Node()" << endl;
	}

	int _val;
	gp::shared_ptr<Node> _next;
	gp::shared_ptr<Node> _prev;
};

int main()
{
	gp::shared_ptr<Node> p1(new Node(1));
	gp::shared_ptr<Node> p2(new Node(2));
	p1->_next = p2;
	p2->_prev = p1;

	return 0;
}

template <class T>
class adjust_delete
{
public:
	void operator()(T* ptr)
	{
		delete[] ptr;
	}
};

class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "A():a" << endl;
	}

	~A()
	{
		cout << "~A()" << endl;
	}

	int _a;
};

int main()
{
	//A* a = new A[10];
	gp::shared_ptr<A> p1(new A[10],adjust_delete<A>());
	gp::shared_ptr<A> p2(new A(1));
	gp::shared_ptr<FILE> p3(fopen("3-20.cpp", "r"), [](FILE* ptr) {
		cout << "fclose(ptr)" << endl;
		fclose(ptr); });

	return 0;
}